import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:largefriends/db/lf_location_db_helper.dart';
import 'package:largefriends/entity/entities/lf_city_entity.dart';
import 'package:largefriends/entity/entities/lf_location_entity.dart';
import 'package:largefriends/res/lf_color.dart';
import 'package:largefriends/res/lf_double_ext.dart';
import 'package:largefriends/res/lf_string_ext.dart';
import 'package:largefriends/res/lf_text_style.dart';
import 'package:largefriends/res/strings/lf_strings.dart';
import 'package:largefriends/utils/lf_scroll_behavior.dart';

import '../entity/entities/db_country_entity.dart';
import '../entity/entities/db_state_entity.dart';
import '../net/lf_api_url.dart';
import '../net/lf_dio_util.dart';
import '../res.dart';
import '../res/lf_fonts.dart';
import '../res/lf_widget_ext.dart';
import '../utils/lf_dialog_utils.dart';

showLfLocationWidget(
    {Function(LfLocationEntity locationEntity)? onConfirm,
    LfLocationEntity? initLocation,
    bool showAnyWhere = false,
    bool passCity = false}) async {
  RxBool hasState = false.obs;
  RxBool hasCity = false.obs;
  RxInt openTag = 0.obs; //1 country. 2.state, 3 city

  Rx<LfLocationEntity> locationEntity =
      Rx<LfLocationEntity>(LfLocationEntity());
  RxList<DbCountryEntity> countryList = RxList.empty(growable: true);
  countryList.value = await LfLocationDbHelper.instance
      .getCountryList(needAnyWhere: showAnyWhere);

  RxList<DbStateEntity> stateList = RxList.empty(growable: true);

  if (initLocation != null) {
    locationEntity.value = LfLocationEntity.fromJson(initLocation.toJson());
    if (initLocation.countryId != null) {
      stateList.clear();
      stateList.value = await LfLocationDbHelper.instance
          .getStateListByCountryId(initLocation.countryId!,
              needAnyWhere: showAnyWhere);
    }
  }
  if (locationEntity.value.stateId.isNullOrEmpty == false) {
    hasState.value = true;
  }
  if (hasState.value && (locationEntity.value.cityId.isNullOrEmpty == false)) {
    hasCity.value = true;
  }
  RxList<LfCityEntity> cityList = RxList.empty(growable: true);

  ScrollController controller = ScrollController();
  await Get.bottomSheet(
      Container(
        decoration: BoxDecoration(
            color: color000000,
            borderRadius: BorderRadius.only(
                topRight: Radius.circular(14.r),
                topLeft: Radius.circular(14.r))),
        child: Column(
          children: [
            Container(
              decoration: BoxDecoration(
                color: color000000,
                borderRadius: BorderRadius.only(
                  topRight: Radius.circular(14.r),
                  topLeft: Radius.circular(14.r),
                ),
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  InkWell(
                    child: Padding(
                        padding: EdgeInsets.symmetric(
                            vertical: 15.h, horizontal: 10.w),
                        child: Text(
                          strCancel.tr,
                          style: lfTextStyle(sp: 18.sp, fontFamily: fontMedium),
                        )),
                    onTap: () {
                      hideSheet();
                    },
                  ),
                  Obx(() {
                    bool isEnable = false;
                    if (hasCity.isTrue && (!passCity)) {
                      if ((locationEntity.value.countryId.isNullOrEmpty ==
                              false) &&
                          (locationEntity.value.stateId.isNullOrEmpty ==
                              false) &&
                          (locationEntity.value.cityId.isNullOrEmpty ==
                              false)) {
                        isEnable = true;
                      } else {
                        isEnable = false;
                      }
                    } else if (hasState.isTrue) {
                      if ((locationEntity.value.countryId.isNullOrEmpty ==
                              false) &&
                          (locationEntity.value.stateId.isNullOrEmpty ==
                              false)) {
                        isEnable = true;
                      } else {
                        isEnable = false;
                      }
                    } else {
                      if ((locationEntity.value.countryId.isNullOrEmpty ==
                          false)) {
                        isEnable = true;
                      } else {
                        isEnable = false;
                      }
                    }
                    return InkWell(
                      child: Padding(
                          padding: EdgeInsets.symmetric(
                              vertical: 15.h, horizontal: 10.w),
                          child: Text(
                            strDone.tr,
                            style: lfTextStyle(
                                sp: 18.sp,
                                fontFamily: fontMedium,
                                color: isEnable
                                    ? colorFF007F
                                    : Colors.transparent),
                          )),
                      onTap: () {
                        if (isEnable) {
                          hideSheet();
                          onConfirm?.call(locationEntity.value);
                        }
                      },
                    );
                  })
                ],
              ),
            ),
            Expanded(
                child: ScrollConfiguration(
              behavior: LfScrollBehavior(),
              child: CustomScrollView(
                controller: controller,
                slivers: [
                  InkWell(
                    child: Padding(
                      padding: EdgeInsets.symmetric(vertical: 10.h),
                      child: Obx(() => Row(
                            children: [
                              10.w.sbw,
                              Text(
                                strCountry.tr,
                                style: lfTextStyle(
                                    sp: 15.sp, fontFamily: fontBold),
                              ),
                              15.w.sbw,
                              Expanded(
                                child: Text(
                                  locationEntity.value.country ?? "",
                                  style: lfTextStyle(
                                      sp: 15.sp,
                                      fontFamily: fontMedium,),
                                  textAlign: TextAlign.end,
                                ),
                              ),
                              AnimatedContainer(
                                duration: const Duration(milliseconds: 100),
                                transform: Matrix4.rotationZ(
                                    (openTag.value == 1) ? pi / 2 : 0),
                                transformAlignment: Alignment.center,
                                child: Icon(Icons.chevron_right,color: colorFEFEFE,size: 20.r,),
                              ),
                              10.w.sbw,
                            ],
                          )),
                    ),
                    onTap: () {
                      if (openTag.value != 1) {
                        openTag.value = 1;
                      } else {
                        openTag.value = 0;
                      }
                    },
                  ).sliverBox,
                  Obx(() => openTag.value == 1
                      ? ListView.builder(
                          physics: const NeverScrollableScrollPhysics(),
                          shrinkWrap: true,
                          itemBuilder: (context, index) {
                            var countryEntity = countryList[index];

                            return InkWell(
                              child: Padding(
                                padding: EdgeInsets.symmetric(
                                    vertical: 5.h, horizontal: 20.w),
                                child: Obx(() {
                                  bool isSelected = countryEntity.id ==
                                      locationEntity.value.countryId;
                                  return Text(countryEntity.name,
                                      style: lfTextStyle(
                                          sp: 15.sp,
                                          fontFamily: fontMedium,
                                          color: isSelected
                                              ? colorFF007F
                                              : colorFEFEFE));
                                }),
                              ),
                              onTap: () async {
                                if (countryEntity.id !=
                                    locationEntity.value.countryId) {
                                  locationEntity.update((val) {
                                    val!.country = countryEntity.name;
                                    val.countryId = countryEntity.id;
                                    val.countAbbr = countryEntity.abbr;
                                    val.state = '';
                                    val.stateId = '';
                                    val.stateAbbr = '';
                                    val.city = '';
                                    val.cityId = '';
                                  });
                                  if (countryEntity.id == "0") {
                                    stateList.clear();
                                    hasState.value = false;
                                    hasCity.value = false;
                                    openTag.value = 0;
                                    return;
                                  }
                                  stateList.clear();
                                  stateList.value = await LfLocationDbHelper
                                      .instance
                                      .getStateListByCountryId(countryEntity.id,
                                          needAnyWhere: showAnyWhere);
                                  if (showAnyWhere && stateList.length == 1) {
                                    hasState.value = false;
                                    hasCity.value = false;
                                  } else if (stateList.isNotEmpty) {
                                    locationEntity.update((val) {
                                      val!.country = countryEntity.name;
                                      val.countryId = countryEntity.id;
                                      val.countAbbr = countryEntity.abbr;
                                      val.state =
                                          showAnyWhere ? "Anywhere" : '';
                                      val.stateId = showAnyWhere ? "0" : '';
                                      val.stateAbbr =
                                          showAnyWhere ? "Anywhere" : '';
                                      val.city = '';
                                      val.cityId = '';
                                    });
                                    openTag.value = 2;
                                    hasState.value = true;
                                    hasCity.value = false;
                                    controller.animateTo(0,
                                        duration:
                                            const Duration(milliseconds: 50),
                                        curve: Curves.linear);
                                  } else {
                                    hasState.value = false;
                                    hasCity.value = false;
                                  }
                                }
                              },
                            );
                          },
                          itemCount: countryList.length,
                        )
                      : empty).sliverBox,
                  Obx(() {
                    var visibility = stateList.isNotEmpty && hasState.value;
                    return Visibility(
                      visible: visibility,
                      child: InkWell(
                        child: Padding(
                            padding: EdgeInsets.symmetric(vertical: 10.h),
                            child: Obx(() => Row(
                                  children: [
                                    10.w.sbw,
                                    Text(
                                      strState.tr,
                                      style: lfTextStyle(
                                          sp: 15.sp, fontFamily: fontBold),
                                    ),
                                    15.w.sbw,
                                    Expanded(
                                      child: Text(
                                        locationEntity.value.state ?? "",
                                        style: lfTextStyle(
                                            sp: 15.sp,
                                            fontFamily: fontMedium,),
                                        textAlign: TextAlign.end,
                                      ),
                                    ),
                                    AnimatedContainer(
                                      duration:
                                          const Duration(milliseconds: 100),
                                      transform: Matrix4.rotationZ(
                                          (openTag.value == 2) ? pi / 2 : 0),
                                      transformAlignment: Alignment.center,
                                      child: Icon(Icons.chevron_right,color: colorFEFEFE,size: 20.r,),
                                    ),
                                    10.w.sbw,
                                  ],
                                ))),
                        onTap: () {
                          if (openTag.value != 2) {
                            openTag.value = 2;
                          } else {
                            openTag.value = 0;
                          }
                        },
                      ),
                    );
                  }).sliverBox,
                  Obx(() {
                    if (openTag.value == 2 &&
                        stateList.isNotEmpty &&
                        hasState.isTrue) {
                      return ListView.builder(
                        physics: const NeverScrollableScrollPhysics(),
                        shrinkWrap: true,
                        itemBuilder: (context, index) {
                          var stateEntity = stateList[index];

                          return InkWell(
                            child: Padding(
                              padding: EdgeInsets.symmetric(
                                  vertical: 5.h, horizontal: 20.w),
                              child: Obx(() {
                                bool isSelected = stateEntity.id ==
                                    locationEntity.value.stateId;
                                return Text(stateEntity.name,
                                    style: lfTextStyle(
                                        sp: 15.sp,
                                        fontFamily: fontMedium,
                                        color: isSelected
                                            ? colorFF007F
                                            : colorFEFEFE));
                              }),
                            ),
                            onTap: () async {
                              if (stateEntity.id !=
                                  locationEntity.value.stateId) {
                                locationEntity.update((val) {
                                  val!.state = stateEntity.name;
                                  val.stateId = stateEntity.id;
                                  val.stateAbbr = stateEntity.abbr;
                                  val.city = '';
                                  val.cityId = '';
                                });
                                cityList.clear();
                              }
                              if (passCity) {
                                hasCity.value = false;
                                return;
                              }
                              if (stateEntity.id == "0") {
                                hasCity.value = false;
                                openTag.value = 0;
                                return;
                              }
                              if (cityList.isEmpty) {
                                showLoading();
                                await LfDio().get<List<LfCityEntity>>(
                                    url: apiCityList,
                                    params: {
                                      "stateId": stateEntity.id
                                    }).then((value) {
                                  cityList.clear();
                                  cityList.addAll(value);
                                  if (showAnyWhere) {
                                    cityList.insert(
                                        0,
                                        LfCityEntity(
                                            cityId: "0", cityName: 'Anywhere'));
                                  }
                                  hasCity.value = cityList.isNotEmpty;
                                  openTag.value = 3;
                                  controller.animateTo(0,
                                      duration:
                                          const Duration(milliseconds: 50),
                                      curve: Curves.linear);
                                  hideLoading();
                                }, onError: (error) {
                                  hideLoading();
                                  if (showAnyWhere) {
                                    cityList.insert(
                                        0,
                                        LfCityEntity(
                                            cityId: "0", cityName: 'Anywhere'));
                                    hasCity.value = cityList.isNotEmpty;
                                    openTag.value = 3;
                                    controller.animateTo(0,
                                        duration:
                                            const Duration(milliseconds: 50),
                                        curve: Curves.linear);
                                  } else {
                                    hasCity.value = false;
                                  }
                                });
                              } else {
                                if (showAnyWhere) {
                                  cityList.removeWhere(
                                      (element) => element.cityId == "0");
                                  cityList.insert(
                                      0,
                                      LfCityEntity(
                                          cityId: "0", cityName: 'Anywhere'));
                                }
                                hasCity.value = cityList.isNotEmpty;
                                openTag.value = 3;
                              }
                            },
                          );
                        },
                        itemCount: stateList.length,
                      );
                    } else {
                      return empty;
                    }
                  }).sliverBox,
                  Obx(() {
                    var visibility = stateList.isNotEmpty &&
                        hasState.value &&
                        hasCity.value &&
                        (!passCity);
                    return Visibility(
                      visible: visibility,
                      child: InkWell(
                        child: Padding(
                          padding: EdgeInsets.symmetric(vertical: 10.h),
                          child: Obx(
                            () => Row(
                              children: [
                                10.w.sbw,
                                Text(
                                  strCity.tr,
                                  style: lfTextStyle(
                                      sp: 15.sp, fontFamily: fontBold),
                                ),
                                15.w.sbw,
                                Expanded(
                                  child: Text(
                                    locationEntity.value.city ?? "",
                                    style: lfTextStyle(
                                        sp: 15.sp,
                                        fontFamily: fontMedium,),
                                    textAlign: TextAlign.end,
                                  ),
                                ),
                                AnimatedContainer(
                                  duration: const Duration(milliseconds: 100),
                                  transform: Matrix4.rotationZ(
                                      (openTag.value == 3) ? pi / 2 : 0),
                                  transformAlignment: Alignment.center,
                                  child: Icon(Icons.chevron_right,color: colorFEFEFE,size: 20.r,),
                                ),
                                10.w.sbw,
                              ],
                            ),
                          ),
                        ),
                        onTap: () async {
                          if (openTag.value == 3) {
                            openTag.value = 0;
                          } else {
                            if (cityList.isEmpty) {
                              showLoading();
                              await LfDio().get<List<LfCityEntity>>(
                                  url: apiCityList,
                                  params: {
                                    "stateId": locationEntity.value.stateId
                                  }).then((value) {
                                cityList.clear();
                                cityList.addAll(value);
                                if (showAnyWhere) {
                                  cityList.removeWhere(
                                      (element) => element.cityId == "0");
                                  cityList.insert(
                                      0,
                                      LfCityEntity(
                                          cityId: "0", cityName: 'Anywhere'));
                                }
                                hasCity.value = cityList.isNotEmpty;
                                openTag.value = 3;
                                hideLoading();
                              }, onError: (error) {
                                if (showAnyWhere) {
                                  if (showAnyWhere) {
                                    cityList.removeWhere(
                                        (element) => element.cityId == "0");
                                    cityList.insert(
                                        0,
                                        LfCityEntity(
                                            cityId: "0", cityName: 'Anywhere'));
                                  }
                                  hasCity.value = cityList.isNotEmpty;
                                  openTag.value = 3;
                                } else {
                                  hasCity.value = false;
                                }
                              });
                            } else {
                              if (showAnyWhere) {
                                cityList.removeWhere(
                                    (element) => element.cityId == "0");
                                cityList.insert(
                                    0,
                                    LfCityEntity(
                                        cityId: "0", cityName: 'Anywhere'));
                              }
                              openTag.value = 3;
                            }
                          }
                        },
                      ),
                    );
                  }).sliverBox,
                  Obx(() {
                    if (openTag.value == 3 &&
                        cityList.isNotEmpty &&
                        hasState.isTrue &&
                        hasCity.isTrue &&
                        (!passCity)) {
                      return ListView.builder(
                        physics: const NeverScrollableScrollPhysics(),
                        shrinkWrap: true,
                        itemBuilder: (context, index) {
                          var cityEntity = cityList[index];

                          return InkWell(
                            child: Padding(
                              padding: EdgeInsets.symmetric(
                                  vertical: 5.h, horizontal: 20.w),
                              child: Obx(() {
                                bool isSelected = cityEntity.cityId ==
                                    locationEntity.value.cityId;
                                return Text(cityEntity.cityName ?? "",
                                    style: lfTextStyle(
                                        sp: 15.sp,
                                        fontFamily: fontMedium,
                                        color: isSelected
                                            ? colorFF007F
                                            : colorFEFEFE));
                              }),
                            ),
                            onTap: () async {
                              if (cityEntity.cityId !=
                                  locationEntity.value.cityId) {
                                locationEntity.update((val) {
                                  val!.city = cityEntity.cityName ?? "";
                                  val.cityId = cityEntity.cityId ?? "";
                                });
                              }
                            },
                          );
                        },
                        itemCount: cityList.length,
                      );
                    } else {
                      return empty;
                    }
                  }).sliverBox,
                ],
              ),
            ))
          ],
        ),
      ),
      enableDrag: false);
}
